local cableSide = "back"
local modemSide
local width, height
local input
local inputLength = 0
local enableWire = colors.blue
local disableWire = colors.red
local inputWire = colors.lime
local verbose = false
local running = false
local consoleText = { }
local modemConnected = "Modem connected successfully"
local modemMissing = "Modem missing, please attach modem"
local author = "Kevin Scroggins"
local nickname = "nitro glycerine"
local email = "nitro404@gmail.com
local website = "http://www.nitro404.com"

function getInput(side)
  return redstone.getInput(side)
end

function sendPulse(side)
  redstone.setOutput(side, true)
  os.sleep(0.25)
  redstone.setOutput(side, false)
end

function getBundledInput(side, wires)
  return colors.test(redstone.getBundledInput(side), wires)
end

function sendBundledPulse(side, wires)
  redstone.setBundledOutput(side, wires)
  os.sleep(0.25)
  redstone.setBundledOutput(side, 0)
end

function sendMessage(s)
  if s == nil then
    return
  end
  
  rednet.broadcast(s)
end

function receiveMessage()
  local senderID, message, distance
  
  while running == true do
    handleMessage(rednet.receive())
  end
end

function handleMessage(senderID, message, distance)
  local cmd
  
  if senderID == nil or message == nil or senderID == os.computerID() then
    return
  end
  
  cmd = parseCommand(message)
  
  if cmd == nil or cmd[0] == nil or cmd[0] == "" then
    return
  elseif cmd[0]:lower() == "lights" then
    if #cmd == 0 or cmd[1] == nill or cmd[1] == "" or cmd[1] == "?" then
      if getBundledInput(cableSide, inputWire) == true then
        sendMessage("lights enabled")
      else
        sendMessage("lights disabled")
      end
    elseif cmd[1]:lower() == "on" then
      addText("Turning lights on")
      sendBundledPulse(cableSide, enableWire)
    elseif cmd[1]:lower() == "off" then
      addText("Turning lights off")
      sendBundledPulse(cableSide, disableWire)
    elseif cmd[1]:lower() == "enabled" then
      addText("lights are on")
    elseif cmd[1]:lower() == "disabled" then
      addText("lights are off")
    else
      addText("Illegal usage of lights command: " .. cmd[1])
    end
  else
    addText("Received unknown command: \"" .. cmd[0] .. "\" from " .. senderID)
  end
end

function handleInput()
  while running == true do
    input = read()
--	addText(input)
	
    if input:lower() == "quit" or input:lower() == "exit" or input:lower() == "stop" then
      stop()
    else
      sendMessage(input)
    end
	
	inputLength = 0
	
	draw()
  end
end

function keyListener()
  local t, k
  
  while running == true do
    t, k = os.pullEvent("key")
	if k == 28 then -- enter
	  inputLength = 0
	elseif k == 14 then -- backspace
	  if inputLength ~= 0 then
	    inputLength = inputLength - 1
	  end
	else
	  inputLength = inputLength + 1
	end
  end
end

function parseCommand(s)
  local cmd = {}
  
  if s == nil then
    return
  end
  
  local i = 0
  for v in string.gmatch(s, "[^ \t]+") do
    cmd[i] = v
    i = i + 1
  end
  
  return cmd
end

function findPeripheral(p)
  for _, v in ipairs(rs.getSides()) do
    if peripheral.isPresent(v) and peripheral.getType(v) == p then
      return v
    end
  end
end

function addText(s)
  table.insert(consoleText, s)
  
  if #consoleText == height then
    table.remove(consoleText, 1)
  end
  
  draw()
end

function draw()
  term.clear()
  
  for i = 1, #consoleText, 1 do
    term.setCursorPos(1, i)
	term.write(consoleText[i])
  end
  
  term.setCursorPos(1, height)
  term.write(">")
  term.setCursorPos(inputLength + 3, height)
end

function initModem()
  modemSide = findPeripheral("modem")
  if modemSide == nil then
    return false
  end
  
  rednet.open(modemSide)
  
  return rednet.isOpen(modemSide)
end

function init()
  width, height = term.getSize()
  
  if initModem() == true then
    if verbose == true then
	  addText(modemConnected)
	end
	
	running = true
  else
    if verbose == true then
      addText(modemMissing)
	end
  end
  
  return running
end

function stop()
  running = false
  
  rednet.close(modemSide)
  os.reboot()
end

function monitor()
  term.clear()
  term.setCursorPos(1, 1)
  
  if init() ~= true then
    print("Initialization failed")
    return
  end
  
  parallel.waitForAll(receiveMessage, draw, handleInput, keyListener)
end

monitor()
